﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Red.Controls.ViewModels;
using Red.Core.Extensions;

namespace Red.Controls.Diagrams.InteropUtils
{
    public class InteropObject : IObject
    {
        #region Data

        private readonly DataItem _dataItem;
        private Dictionary<string, InteropProperty> _properties;

        #endregion Data

        #region C-tor

        public InteropObject( DataItem dataItem )
        {
            _dataItem = dataItem;
        }

        #endregion C-tor

        #region Public methods

        public async Task Accept( InteropObjectInitializer initializer )
        {
            _properties = await initializer.Visit( _dataItem );
        }

        #endregion Public methods

        #region IObject implementation

        public string ReadProperty( string propertyName )
        {
            InteropProperty property;
            if ( _properties.TryGetValue( propertyName, out property ) )
            {
                return property.Values.First().Value;
            }

            return null;
        }

        public void WriteProperty( string propertyName, string value, string valueID = "", string operationID = "" )
        {
            InteropProperty property;
            if ( _properties.TryGetValue( propertyName, out property ) )
                property.SetValue( value, operationID );
        }

        public void WritePropertyDirect( string propertyName, string value, string valueID = "", string operationID = "" )
        {
            if ( string.IsNullOrEmpty( operationID ) )
                operationID = Guid.NewGuid().ToString();

            _dataItem.Execute( "writeProperty", propertyName, value, operationID );
        }

        public IProperty GetProperty( string propertyName )
        {
            if ( string.IsNullOrEmpty( propertyName ) )
                return null;

            InteropProperty property;
            if ( _properties.TryGetValue( propertyName, out property ) )
                return property;

            return null;
        }

        public string ID
        {
            get { return ReadProperty( "Id" ); }
        }

        public string Class
        {
            get { return ReadProperty( "Class" ); }
        }

        public bool IsRoot
        {
            get { return false; } // TODO: do actual root check
        }

        public IEnumerable<string> GetProperties()
        {
            return _properties.Keys.ToList();
        }

        public DataItem GetDataItem()
        {
            return _dataItem;
        }

        #endregion IObject implementation
    }
}
